package com.wy.demo.makeImage;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import org.junit.Test;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

public class ScreenshotService {

    // ===========================================
    // 方式一：使用绝对路径的完整配置方式
    // ===========================================
    // 配置字段
    private String htmlTemplatePath;    // HTML模板路径
    private String outputPath;          // 输出路径
    private String executionPath;       // 执行位置（node项目路径）
    private String jsFilePath;          // JS文件位置

    /**
     * 方式一：设置完整路径配置参数
     *
     * @param htmlTemplatePath HTML模板文件夹路径
     * @param outputPath       输出文件路径
     * @param executionPath    执行位置（包含node_modules的目录）
     * @param jsFilePath       JS截图脚本文件路径
     */
    public void setFullPathConfiguration(String htmlTemplatePath, String outputPath, String executionPath, String jsFilePath) {
        this.htmlTemplatePath = htmlTemplatePath;
        this.outputPath = outputPath;
        this.executionPath = executionPath;
        this.jsFilePath = jsFilePath;

        System.out.println("📋 完整路径配置已设置：");
        System.out.println("  HTML模板路径: " + htmlTemplatePath);
        System.out.println("  输出路径: " + outputPath);
        System.out.println("  执行位置: " + executionPath);
        System.out.println("  JS文件路径: " + jsFilePath);
    }

    /**
     * 方式一 - 步骤1：生成HTML文件
     */
    public String generateHtmlFromTemplate(String templateName, Map<String, Object> data) throws Exception {
        if (!isFullPathConfigurationValid()) {
            throw new IllegalStateException("完整路径配置不完整，请先调用 setFullPathConfiguration() 方法");
        }

        // 1. 初始化 FreeMarker 配置
        Configuration cfg = new Configuration(new Version("2.3.31"));
        cfg.setDirectoryForTemplateLoading(new File(htmlTemplatePath));
        cfg.setDefaultEncoding("UTF-8");

        // 2. 加载模板
        Template template = cfg.getTemplate(templateName);

        // 3. 渲染模板
        StringWriter out = new StringWriter();
        template.process(data, out);
        String html = out.toString();

        // 4. 保存 HTML 到文件
        Path htmlPath = Paths.get(outputPath, "rendered.html");
        Files.createDirectories(htmlPath.getParent());
        Files.write(htmlPath, html.getBytes("UTF-8"));

        String htmlFilePath = htmlPath.toAbsolutePath().toString();
        System.out.println("✅ 步骤1完成 - HTML文件生成成功：" + htmlFilePath);
        return htmlFilePath;
    }

    /**
     * 方式一 - 步骤2：从HTML文件生成截图
     */
    public void generateScreenshotFromHtml(String htmlFilePath, String outputImageName) throws Exception {
        if (!isFullPathConfigurationValid()) {
            throw new IllegalStateException("完整路径配置不完整，请先调用 setFullPathConfiguration() 方法");
        }

        String outputImagePath = Paths.get(outputPath, outputImageName).toString();
        ProcessBuilder pb = new ProcessBuilder("node", jsFilePath, htmlFilePath, outputImagePath);
        pb.directory(new File(executionPath));
        pb.inheritIO();
        Process process = pb.start();
        int exitCode = process.waitFor();

        if (exitCode == 0) {
            System.out.println("✅ 步骤2完成 - 图片生成成功：" + outputImagePath);
        } else {
            System.err.println("❌ 步骤2失败 - 图片生成失败！");
        }
    }

    /**
     * 方式一：完整流程（两步合一）
     */
    public void generateScreenshotFullPath(String templateName, String outputImageName, Map<String, Object> data) throws Exception {
        String htmlFilePath = generateHtmlFromTemplate(templateName, data);
        generateScreenshotFromHtml(htmlFilePath, outputImageName);
    }

    /**
     * 验证完整路径配置是否完整
     */
    private boolean isFullPathConfigurationValid() {
        return htmlTemplatePath != null && !htmlTemplatePath.isEmpty() &&
                outputPath != null && !outputPath.isEmpty() &&
                executionPath != null && !executionPath.isEmpty() &&
                jsFilePath != null && !jsFilePath.isEmpty();
    }

    // ===========================================
    // 方式二：使用jar包资源的简化配置方式
    // ===========================================
    // 简化配置字段
    private String simpleOutputPath;
    private String simpleExecutionPath;

    /**
     * 方式二：设置jar包资源简化配置
     * 模板和JS脚本将从classpath中读取
     *
     * @param outputPath 输出文件路径（可选，默认为当前目录下的output文件夹）
     */
    public void setResourceConfiguration(String outputPath) {
        // 如果没有指定输出路径，使用默认路径
        if (outputPath == null || outputPath.isEmpty()) {
            outputPath = System.getProperty("user.dir") + File.separator + "output";
        }

        this.simpleOutputPath = outputPath;
        this.simpleExecutionPath = System.getProperty("user.dir"); // 当前工作目录

        System.out.println("📋 jar包资源配置已设置：");
        System.out.println("  输出路径: " + this.simpleOutputPath);
        System.out.println("  执行位置: " + this.simpleExecutionPath);
        System.out.println("  模板和JS脚本将从jar包内读取");
    }

    /**
     * 方式二 - 步骤1：从jar包资源生成HTML文件
     */
    public String generateHtmlFromResource(String templateName, Map<String, Object> data) throws Exception {

        // 1. 初始化 FreeMarker 配置，使用classpath
        Configuration cfg = new Configuration(new Version("2.3.31"));
        cfg.setClassForTemplateLoading(this.getClass(), "/templates");
        cfg.setDefaultEncoding("UTF-8");

        // 2. 加载模板
        Template template = cfg.getTemplate(templateName);

        // 3. 渲染模板
        StringWriter out = new StringWriter();
        template.process(data, out);
        String html = out.toString();

        // 4. 保存 HTML 到文件
        String outputPath = "C:\\Users\\wy\\Desktop\\新建文件夹";
        Path outputDir = Paths.get(outputPath);
//        Files.createDirectories(outputDir);
        Path htmlPath = outputDir.resolve("rendered.html");
        Files.write(htmlPath, html.getBytes(StandardCharsets.UTF_8));
        String htmlFilePath = htmlPath.toAbsolutePath().toString();
        System.out.println("✅ 步骤1完成 - HTML文件生成成功：" + htmlFilePath);
        return htmlFilePath;
    }

    /**
     * 方式二 - 步骤2：从HTML文件生成截图（使用jar包内的JS脚本）
     */
    public void generateScreenshotFromHtmlResource(String htmlFilePath, String outputImageName) throws Exception {

        // 从jar包中提取JS脚本到临时文件
        String jsScriptPath = extractJsScript();

        try {
            String outputImagePath = Paths.get(simpleOutputPath, outputImageName).toString();
            ProcessBuilder pb = new ProcessBuilder("node", jsScriptPath, htmlFilePath, outputImagePath);
            pb.directory(new File(simpleExecutionPath));
            pb.inheritIO();
            Process process = pb.start();
            int exitCode = process.waitFor();

            if (exitCode == 0) {
                System.out.println("✅ 步骤2完成 - 图片生成成功：" + outputImagePath);
            } else {
                System.err.println("❌ 步骤2失败 - 图片生成失败！");
            }
        } finally {
            // 清理临时JS文件
            Files.deleteIfExists(Paths.get(jsScriptPath));
        }
    }

    /**
     * 方式二：完整流程（两步合一）
     */
    public void generateScreenshotFromResources(String templateName, String outputImageName, Map<String, Object> data) throws Exception {
        String htmlFilePath = generateHtmlFromResource(templateName, data);
        generateScreenshotFromHtmlResource(htmlFilePath, outputImageName);
    }

    /**
     * 从jar包中提取JS脚本到临时文件
     */
    private String extractJsScript() throws IOException {
        InputStream jsStream = this.getClass().getResourceAsStream("/screenshot.js");
        if (jsStream == null) {
            throw new FileNotFoundException("在jar包中找不到 /screenshot.js 文件");
        }

        // 创建临时文件
        Path tempJsFile = Files.createTempFile("screenshot", ".js");

        // 复制内容到临时文件
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(jsStream));
             BufferedWriter writer = Files.newBufferedWriter(tempJsFile)) {

            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.newLine();
            }
        }

        System.out.println("📄 JS脚本已提取到临时文件：" + tempJsFile.toAbsolutePath());
        return tempJsFile.toAbsolutePath().toString();
    }

    @Test
    public  void test2() throws Exception {
        Map<String, Object> data = getData();
        ScreenshotService service2 = new ScreenshotService();
//        service2.setResourceConfiguration(null); // 使用默认输出路径

        // 方式二 - 分步执行
//        System.out.println("\n--- 分步执行 ---");
//        String htmlFile2 = service2.generateHtmlFromResource("order.html", data);
//        service2.generateScreenshotFromHtmlResource(htmlFile2, "order_resource_step_by_step.png");

        // 方式二 - 一步完成
        System.out.println("\n--- 一步完成 ---");
        service2.generateScreenshotFromResources("order.html", "order_from_resources.png", data);
    }
    public void test1() throws Exception {
        Map<String, Object> data = getData();

        System.out.println("==================================================");
        System.out.println("方式一：使用绝对路径配置演示");
        System.out.println("==================================================");

        // 方式一：使用绝对路径配置
        ScreenshotService service1 = new ScreenshotService();
        service1.setFullPathConfiguration(
                "D:\\gitee_versionControllerProject\\common-project-related\\72生成需要的图片\\makeImage\\src\\main\\resources\\templates", // HTML模板路径
                "D:\\gitee_versionControllerProject\\common-project-related\\72生成需要的图片\\makeImage\\output", // 输出路径
                "D:\\gitee_versionControllerProject\\common-project-related\\72生成需要的图片\\makeImage", // 执行位置
                "D:\\gitee_versionControllerProject\\common-project-related\\72生成需要的图片\\makeImage\\src\\main\\resources\\screenshot.js" // JS文件路径
        );

        // 方式一 - 分步执行
        System.out.println("\n--- 分步执行 ---");
        String htmlFile1 = service1.generateHtmlFromTemplate("order.html", data);
        service1.generateScreenshotFromHtml(htmlFile1, "order_step_by_step.png");

        // 方式一 - 一步完成
        System.out.println("\n--- 一步完成 ---");
        service1.generateScreenshotFullPath("order.html", "order_full_path.png", data);

        System.out.println("\n==================================================");
        System.out.println("方式二：使用jar包资源配置演示");
        System.out.println("==================================================");

    }
    private static Map<String, Object> getData() {
        Map<String, Object> data = new HashMap<>();
        data.put("orderNo", "20250803001");
        data.put("customerName", "张三");
        data.put("orderTime", "2025-08-03 14:30:00");

        List<Map<String, Object>> items = new ArrayList<>();

        Map<String, Object> item1 = new HashMap<>();
        item1.put("name", "商品A");
        item1.put("price", 20);
        item1.put("quantity", 2);
        item1.put("total", 40);

        Map<String, Object> item2 = new HashMap<>();
        item2.put("name", "商品B");
        item2.put("price", 30);
        item2.put("quantity", 1);
        item2.put("total", 30);

        items.add(item1);
        items.add(item2);
        data.put("items", items);
        return data;
    }
}
